﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;
using System.IO;
using System.Diagnostics;

namespace FindFileInSolutionLib.Forms
{
    public partial class SearchForm : Form
    {
        private DTE2 _applicationObject;
        public SearchForm(DTE2 application)
        {
            InitializeComponent();
            _applicationObject = application;

            dataGridView1.AutoGenerateColumns = false;

            //_applicationObject.Events.SolutionEvents.Opened += SolutionEvents_Opened;
            //_applicationObject.Events.SolutionItemsEvents.ItemAdded
            //_applicationObject.Events.SolutionItemsEvents.ItemRemoved
            //_applicationObject.Events.SolutionItemsEvents.ItemRenamed

            dataTable.Columns.Add("Icon", typeof(Image));
            dataTable.Columns.Add("Filename", typeof(string));
            dataTable.Columns.Add("Project", typeof(string));
            dataTable.Columns.Add("Path", typeof(string));

            dataGridView1.DataSource = dataTable;
        }

        private void SearchForm_Load(object sender, EventArgs e)
        {
            DateTime start = DateTime.Now;

            //m_UpdateTimer.Interval = 300;
            //m_UpdateTimer.Tick += m_UpdateTimer_Tick;

            Solution solution = _applicationObject.Solution;
            if (solution != null)
            {
                foreach (Project proj in solution.Projects)
                {
                    //AddItem("PROJECT (FullName): " + proj.FullName);
                    //AddItem("PROJECT (Name): " + proj.Name);

                    //proj.Kind

                    ProcessProjectItems(proj.Name, proj.Name, proj.ProjectItems);
                }
            }

            m_FileCount = dataGridView1.Rows.Count;
            this.Text = m_FileCount + " Files";
            //this.Text = "[" + dataGridView1.Rows.Count;

            dataGridView1.Sort(ColumnFilename, ListSortDirection.Ascending);

            ColumnIcon.Width = 21;
            //ColumnIcon.Width = ColumnIcon.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCellsExceptHeader, true);
            ColumnFilename.Width = ColumnFilename.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true) + 10;
            ColumnProject.Width = ColumnProject.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true) + 10;
            //ColumnPath.Width = ColumnPath.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true) + 10;

            TimeSpan span = DateTime.Now - start;
            this.Text += " Loading took " + span.TotalMilliseconds + " ms";
        }

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            LoadSettings();
        }

        // SaveSettings
        // ---------------------------------------------------------------------
        private void SaveSettings()
        {
            Properties.Settings.Default.LastSearchString = textBox1.Text;
            Properties.Settings.Default.SearchFormSize = this.Size;
            Properties.Settings.Default.SearchFormLocation = this.Location;
            Properties.Settings.Default.DefaultSettings = false;

            Properties.Settings.Default.Save();
        }

        // LoadSettings
        // ---------------------------------------------------------------------
        private void LoadSettings()
        {
            if (Properties.Settings.Default.DefaultSettings != true)
            {
                textBox1.Text = Properties.Settings.Default.LastSearchString;
                textBox1.SelectAll();
                this.Size = Properties.Settings.Default.SearchFormSize;
                this.Location = Properties.Settings.Default.SearchFormLocation;
            }
        }

        void ProcessProjectItems(string ProjectName, string PrePath, ProjectItems projItems)
        {
            const string KIND_FILE   = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}";
            const string KIND_FOLDER = "{66A26722-8FB5-11D2-AA7E-00C04F688DDE}";

            if (projItems == null)
            {
                return;
            }

            foreach (ProjectItem projItem in projItems)
            {
                string tempProjectName = ProjectName;

                string kind = projItem.Kind;
                string name = projItem.Name;
                string newPrePath = PrePath + " >> " + name;
                ProjectItems nextProjItems = projItem.ProjectItems;
                if (kind == KIND_FILE)
                {
                    // to get the full path:
                    string temp = string.Empty;
                    for (short i = 0; i < projItem.FileCount; i++)
                    {
                        temp = projItem.FileNames[i];
                    }

                    AddItem(name, ProjectName, temp);
                }
                else if (kind == KIND_FOLDER)
                {
                    Project tempProj = projItem.SubProject;
                    if (tempProj != null)
                    {
                        nextProjItems = tempProj.ProjectItems;
                        tempProjectName = /*tempProjectName + "\\" +*/ tempProj.Name;
                    }
                }

                ProcessProjectItems(tempProjectName, newPrePath, nextProjItems);
            }
        }

        private void SearchForm_Shown(object sender, EventArgs e)
        {
            textBox1.Focus();
        }

        public override bool PreProcessMessage(ref Message msg)
        {
            return base.PreProcessMessage(ref msg);
        }

        // ProcessCmdKey
        // Used to implement form-wide shortcut keys
        // ---------------------------------------------------------------------
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Up))
            {
                if (dataGridView1.CurrentRow != null)
                {
                    int index = dataGridView1.CurrentRow.Index - 1;
                    if (index >= 0)
                    {
                        dataGridView1.CurrentCell = dataGridView1.Rows[index].Cells[0];
                    }
                }
                return true;
            }
            else if (keyData == (Keys.Down))
            {
                if (dataGridView1.CurrentRow != null)
                {
                    int index = dataGridView1.CurrentRow.Index + 1;
                    if (index < dataGridView1.Rows.Count)
                    {
                        dataGridView1.CurrentCell = dataGridView1.Rows[index].Cells[0];
                    }
                }
                return true;
            }
            else if (keyData == (Keys.Enter))
            {
                FileSelected();
                return true;
            }
            else if (keyData == (Keys.Escape))
            {
                this.Close();
                return true;
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        void SearchThread()
        {
            //this.Invoke(new Action(() => UpdateForm(true, true)));
        }

        //Timer m_UpdateTimer = new Timer();
        //void m_UpdateTimer_Tick(object sender, EventArgs e)
        //{
        //    UpdateForm();
        //    m_UpdateTimer.Stop();
        //}

        //private void UpdateForm()
        //{
        //}

        Image m_FileIcon = Properties.Resources.icon_16x16_file;
        int m_FileCount = 0;
        void AddItem(string file, string projectName, string path)
        {
            m_FileCount++;

            //SolutionFile solutionFile = new SolutionFile();
            //solutionFile.SearchString = file.ToLower();
            //solutionFile.Filename = file;
            //solutionFile.Project = projectName;
            //solutionFile.Path = path;
            //solutionFileBindingSource.Add(solutionFile);
            //bs1.Add(solutionFile);

            dataTable.Rows.Add(m_FileIcon, file, projectName, path);
        }

        DataTable dataTable = new DataTable();

        //BindingSource bs1 = new BindingSource();
        //BindingSource bs2 = new BindingSource();

        //private System.Threading.Thread m_SearchThread;
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string searchString = textBox1.Text.ToLower().Trim();
            string[] searchStrings = searchString.Split(' ');

            StringBuilder stringBuilder = new StringBuilder();
            bool First = true;
            foreach (string tempString in searchStrings)
            {
                if (tempString != string.Empty)
                {
                    if (!First)
                    {
                        stringBuilder.Append(" AND ");
                    }
                    First = false;
                    stringBuilder.Append("Filename LIKE '%" + tempString + "%'");
                }
            }

            try
            {
                dataTable.DefaultView.RowFilter = stringBuilder.ToString();

                if (dataGridView1.Rows.Count > 0)
                {
                    dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
                }

                int newCount = dataTable.DefaultView.Count;
                this.Text = "[" + newCount + " of " + m_FileCount + "]";
                
            }
            catch (Exception ex)
            { 
                // do nothing for now...
                Debug.Assert(false, ex.Message);
            }

            return;

            //BindingSource bsSource = solutionFileBindingSource;
            //BindingSource bsCurrent;
            //BindingSource bsNew;
            //if (dataGridView1.DataSource == bs1)
            //{
            //    bsCurrent = bs1;
            //    bsNew = bs2;
            //}
            //else
            //{
            //    bsCurrent = bs2;
            //    bsNew = bs1;
            //}

            //foreach (SolutionFile solutionFile in bsSource)
            //{
            //    if (solutionFile.SearchString.Contains(searchString))
            //    {
            //        bsNew.Add(solutionFile);
            //    }
            //}

            //dataGridView1.DataSource = bsNew;
            //bsCurrent.Clear();

            //if (m_SearchThread == null || m_SearchThread.IsAlive == false)
            //{
            //    m_UpdateTimer.Stop();
            //    m_SearchThread = new System.Threading.Thread(SearchThread);
            //    m_SearchThread.Start();
            //}
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
                return;

            FileSelected();
        }

        private void FileSelected()
        {
            object data = dataGridView1.Rows[dataGridView1.CurrentRow.Index].DataBoundItem;
            if (data != null && data is DataRowView)
            {
                DataRowView dataRow = data as DataRowView;
                object path = dataRow["Path"];
                if (path != null && path is string)
                {
                    string strPath = path as string;
                    _applicationObject.ItemOperations.OpenFile(strPath);
                    //_applicationObject.ExecuteCommand("File.OpenFile", "\"" + strPath + "\"");
                    this.Close();
                }
            }
        }

        private void SearchForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveSettings();
        }
    }
}
